/*
 * Copyright (c) 2015-present, Sinosoft, Inc. All rights reserved.
 *
 * This copyright notice shall be included in all copies or substantial portions of the software.
 * You may not use, copy, modify, and distribute this file and software in source code or binary
 * form except in compliance with the License.
 */

package com.atom.common.util;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import org.apache.log4j.Logger;

public class HttpUtil {
  
  static Logger logger = Logger.getLogger(HttpUtil.class);

  private static final String CHARSET = "UTF-8";
  private static final int DEFAULT_CONNECTION_TIMEOUT = (20 * 1000); // 20seconds
  private static final int DEFAULT_SOCKET_TIMEOUT = (30 * 1000); // 30seconds


  public static String get(final String url, final Map<String, String> params) {
    logger.info("HTTP GET METHOD BEGIN");
    HttpURLConnection conn = null;
    DataOutputStream outStream = null;
    try {
      String newUrl = null;
      if(params==null || params.isEmpty())
        newUrl = url;
      else
        newUrl = url.contains("?") ? url+"&"+parseParams(params) : url+"?"+parseParams(params);
      logger.info("URL : " + newUrl);
      URL realUrl = new URL(newUrl);
      conn = (HttpURLConnection) realUrl.openConnection();
      conn.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT);
      conn.setReadTimeout(DEFAULT_SOCKET_TIMEOUT);
      conn.setUseCaches(false);
      conn.setDoOutput(true);
      conn.setRequestProperty("Connection", "Keep-Alive");
      conn.setRequestProperty("Charset", CHARSET);
      conn.setRequestProperty("user-agent",
          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
      conn.connect();

      if (conn.getResponseCode() == 200) {
        InputStream in = conn.getInputStream();
        StringBuffer sb = new StringBuffer();
        InputStreamReader reader = new InputStreamReader(in, CHARSET);
        char[] buff = new char[1024];
        int len;
        while ((len = reader.read(buff)) > 0) {
          sb.append(buff, 0, len);
        }
        return sb.toString();
      } else {
        System.out.println(conn.getResponseCode());
        throw new Exception("ResponseCode=" + conn.getResponseCode());
      }

    } catch (IOException ex) {
      logger.error("error message = {}" + ex.getMessage());

    } catch (Exception e) {
      logger.error("error message = {}" + e.getMessage(), e);
    } finally {
      if (null != outStream) {
        try {
          outStream.close();
        } catch (IOException e) {
          logger.error("error message = {}" + e.getMessage(), e);
        }
      }
      if (null != conn) {
        conn.disconnect();
      }
    }

    return null;
  }

  public static String post(final String url, final Map<String, String> params) {
    logger.info("HTTP POST METHOD BEGIN");
    HttpURLConnection conn = null;
    DataOutputStream outStream = null;
    try {
      logger.info("URL : " + url);
      URL realUrl = new URL(url);
      byte[] data = parseParams(params).getBytes(CHARSET);
      logger.info("data : " + new String(data, CHARSET));
      conn = (HttpURLConnection) realUrl.openConnection();
      conn.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT);
      conn.setReadTimeout(DEFAULT_SOCKET_TIMEOUT);
      conn.setUseCaches(false);
      conn.setDoOutput(true);
      conn.setRequestProperty("Connection", "Keep-Alive");
      conn.setRequestProperty("Charset", CHARSET);
      conn.setRequestProperty("user-agent",
          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
      conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
      conn.setRequestProperty("Content-Length", String.valueOf(data.length));
      outStream = new DataOutputStream(conn.getOutputStream());
      outStream.write(data);
      outStream.flush();

      if (conn.getResponseCode() == 200) {
        InputStream in = conn.getInputStream();
        StringBuffer sb = new StringBuffer();
        InputStreamReader reader = new InputStreamReader(in, CHARSET);
        char[] buff = new char[1024];
        int len;
        while ((len = reader.read(buff)) > 0) {
          sb.append(buff, 0, len);
        }
        return sb.toString();
      } else {
        throw new Exception("ResponseCode=" + conn.getResponseCode());
      }

    } catch (IOException ex) {
      logger.error("error message = {}" + ex.getMessage());
    } catch (Exception e) {
      logger.error("error message = {}" + e.getMessage(), e);
    } finally {
      if (null != outStream) {
        try {
          outStream.close();
        } catch (IOException e) {
          logger.error("error message = {}" + e.getMessage(), e);
        }
      }
      if (null != conn) {
        conn.disconnect();
      }
    }

    return null;
  }
  
  public static String getUrl(final String url, final Map<String, String> params) {
    String newUrl = null;
    if(params==null || params.isEmpty())
      newUrl = url;
    else
      newUrl = url.contains("?") ? url+"&"+parseParams(params) : url+"?"+parseParams(params);
    logger.info("URL : " + newUrl);
    return newUrl;
  }

  private static String parseParams(Map<String, String> params) {
    if (params == null || params.isEmpty())
      return "";

    StringBuilder builder = new StringBuilder();
    for (Map.Entry<String, String> entry : params.entrySet()) {
      String value = entry.getValue() == null ? "" : entry.getValue();
      builder.append(entry.getKey() + "=" + value + "&");
    }
    builder.deleteCharAt(builder.length()-1);
    return builder.toString();
  }
}
